#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <time.h>
#include "../common.h"
extern "C" {
#include "../yy.h"
}
#include "../sizer.h"
#include "../pcoder.h"
#include "../display.h"
#include "pic16e.h"
#include "pic16e_asm.h"
#include "pic16e_inst.h"

void PIC16E :: parseDivModItem(Item *ip, int idx, int c){
    char* code;
    if (c){ code = (char*)"div "; }
    else{ code = (char*)"rem "; }
	switch (ip->type) {
		case CON_ITEM: {
			if (idx == 2){
				ASM_CODE(_LI,_R_A4,ip->val.i);
			}else if (idx == 3){
				ASM_CODE(_LI,_R_A5,ip->val.i);
			}
		}break;	
		case ID_ITEM:{
			if (ip->attr->isStatic == -1){
				char buf[64];
				if (idx == 2){
						sprintf(buf,"\tlui \ta6,%%hi(%s)\n\tlw  \ta4,%%lo(%s)(a6)\n", ip->vname, ip->vname); 
						ASM_OUTP(buf);
				}else if (idx == 3){
						sprintf(buf,"\tlui \ta6,%%hi(%s)\n\tlw  \ta5,%%lo(%s)(a6)\n", ip->vname, ip->vname); 
						ASM_OUTP(buf);
				}else if (idx == 1){
					/**
							lui     a5,%hi(a)
							sw      a4,%lo(a)(a5)
					 */
					ASM_CODE(code, _R_A4, _R_A4, _R_A5);
					sprintf(buf,"\tlui \ta5,%%hi(%s)\n\tsw  \ta4,%%lo(%s)(a5)\n", ip->vname, ip->vname); 
					ASM_OUTP(buf);
				}
				break;
			}
			
			if (curFunc != NULL){
				if (ip->fname != curFunc->name){
					errPrint("function not matched error");
				}
				Dnode* dp = serachVarable(ip->vname);	
				if (idx == 2){
					ASM_CODE(_LW,_R_A4, dp->memStr);
				}else if (idx == 3){
					ASM_CODE(_LW,_R_A5, dp->memStr);
				}else if (idx == 1){
					ASM_CODE(code, _R_A5, _R_A4, _R_A5);
					ASM_CODE(_SW,_R_A5, dp->memStr);
					ASM_CODE(_LI,_R_A5, 0);
				}
			}
		}break;
		case ACC_ITEM:{
			ASM_CODE(_MUL, _R_A0, _R_A4, _R_A5);
		}break;
		case TEMP_ITEM:{
			if (curFunc != NULL){
				if (idx == 1){
					char buf[64]; sprintf(buf,"\t%s\tt%d, a4, a5\n", code,ip->memRgx); ASM_OUTP(buf);
				} else if (idx == 2) {
					char buf[64]; sprintf(buf,"\tmv  \ta4, t%d\n", ip->memRgx); ASM_OUTP(buf);
				} else if (idx == 3){
					char buf[64]; sprintf(buf,"\tmv  \ta5, t%d\n", ip->memRgx); ASM_OUTP(buf);
				}
			}
		}break;
		default:
			errPrint("gen mul isa error!");
	}
}
void PIC16E :: div(int code, Item *ip0, Item *ip1, Item *ip2){
	parseDivModItem(ip1, 2,  1);
	parseDivModItem(ip2, 3,  1);
	parseDivModItem(ip0, 1,  1);
}
void PIC16E :: mod(int code, Item *ip0, Item *ip1, Item *ip2){
	parseDivModItem(ip1, 2,  0);
	parseDivModItem(ip2, 3,  0);
	parseDivModItem(ip0, 1,  0);
}

void PIC16E :: djnz(int code, Item *ip0, Item *ip1)
{
;
}